//
//  PlayersManager.cpp
//  DiceWar
//
//  Created by xiaofeng on 29/6/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#include "PlayersManager.h"
#include "Player.h"
#include "HumanPlayer.h"
#include "RobotPlayer.h"
#include "GameMaster.h"

PlayersManager::PlayersManager()
: m_currentPlayerIndex(0) {}

PlayersManager::~PlayersManager() {}

bool PlayersManager::start()
{
    releaseAllPlayers();
    
    const GameMaster& gameMaster = GameMaster::instance();
    const int kNumPlayers = gameMaster.getNumPlayers();
    const PlayerType kHumanType = gameMaster.getHumanPlayerType();
    
    if (gameMaster.isPeopleVsPeople()) 
    {
        if (!createPlayersForPlayerVsPlayer(kNumPlayers)) return false;
    }
    else if (gameMaster.isPeopleVsAI()) 
    {
        if (!createPlayersForPlayerVsAI(kNumPlayers, kHumanType)) return false;
    }
    
    std::random_shuffle(m_players.begin(), m_players.end());
    m_currentPlayerIndex = 0;
    return true;
}

void PlayersManager::gotoNextPlayer()
{
    m_currentPlayerIndex++;
    if (m_currentPlayerIndex >= getNumPlayers()) m_currentPlayerIndex = 0;

    startRound();
}

int PlayersManager::getNumAlivePlayers() const
{
    int numAlivePlayers = 0;
    for (PlayersVec::const_iterator iter = m_players.begin(); iter != m_players.end(); ++iter)
    {
        Player* pPlayer = *iter;
        if (!pPlayer) continue;
        if (!pPlayer->isDead()) numAlivePlayers++;
    }
    
    return numAlivePlayers;
}

PlayerType PlayersManager::getCurrentPlayer() const
{
    const Player* pPlayer = m_players[m_currentPlayerIndex];
    if (!pPlayer) return kInvalidPlayer;
    
    return pPlayer->getType();
}

void PlayersManager::startRound()
{
    Player* pPlayer = m_players[m_currentPlayerIndex];
    if (pPlayer) pPlayer->startRound();
}

bool PlayersManager::createPlayersForPlayerVsPlayer(int numPlayers)
{
    for (int index = 0; index < numPlayers; index++)
    {
        PlayerType currentType = static_cast<PlayerType>(index);
        Player* humanPlayer = createHumanPlayer(currentType);
        if (!humanPlayer) return false;
        m_players.push_back(humanPlayer);
    }
    
    return true;
}

bool PlayersManager::createPlayersForPlayerVsAI(int numPlayers, PlayerType humanType)
{
    Player* pHumanPlayer = createHumanPlayer(humanType);
    if (!pHumanPlayer) return false;
    m_players.push_back(pHumanPlayer);
    
    for (int playersLeft = numPlayers - 1, index = 0; index < kInvalidPlayer && playersLeft > 0; index++)
    {
        PlayerType currentType = static_cast<PlayerType>(index);
        if (currentType == humanType) continue;
        
        Player* robotPlayer = createRobotPlayer(currentType);
        if (!robotPlayer) return false;
        m_players.push_back(robotPlayer);
        
        playersLeft--;
    }
    
    return true;
}


Player* PlayersManager::createHumanPlayer(PlayerType type)
{
    Player* pPlayer = new HumanPlayer(type);
    CCAssert(pPlayer, "Can't create the Human Player!");
    if (!pPlayer) return NULL;
    
    pPlayer->autorelease();
    pPlayer->retain();
    return pPlayer;
}

Player* PlayersManager::createRobotPlayer(PlayerType type)
{
    Player* pPlayer = new RobotPlayer(type);
    CCAssert(pPlayer, "Can't create the Robot Player!");
    if (!pPlayer) return NULL;
    
    pPlayer->autorelease();
    pPlayer->retain();
    return pPlayer;
}

void PlayersManager::releaseAllPlayers()
{
    for (PlayersVec::iterator iter = m_players.begin(); iter != m_players.end(); ++iter) 
    {
        Player* pPlayer = *iter;
        pPlayer->release();
    }
    
    m_players.clear();
}

int PlayersManager::getNumPlayers()
{
    return static_cast<int>(m_players.size());
}
